﻿/*****************************************************

 **Copyright(C), 2015-2025, ruima Technology.

 **Version:0.0.0.0

 **Author:jay

 **Date:2022年5月26日

 **Description:封装访问access和mysql数据库的接口
 ** 生成sql的接口支支持等值条件，包含特殊条件的应使用直接传入sql的接口

 *****************************************************/
#ifndef DATABASEOPERATE_H
#define DATABASEOPERATE_H

#include <QObject>
#include <QSqlDatabase>
#include "commondef.h"

class Database : public QObject
{
public:
    explicit Database(QObject *parent = nullptr);

    virtual ~Database();

    /**
     * @brief getXorEncryptDecrypt 异或加密算法
     * @param str 明文
     * @param key 密钥
     * @return 密文
     */
    QString getXorEncryptDecrypt(const QString&str, char key);

    bool connectToDb(DataBaseType type, const MSS& info);

    /**
     * @brief connectToMsodbc 连接到access数据库
     * @param dsn 连接命令
     * @return 成功返回true
     */
    bool connectToMsodbc(const QString& dsn);

    /**
     * @brief connectToMySql 连接到数据库
     * @param host 主机
     * @param port 端口
     * @param dbName 数据库名称
     * @param username 用户名
     * @param password 密码
     * @return 成功返回true
     */
    bool connectToMySql(const QString& host, int port, const QString& dbName, const QString& username, const QString& password);

    /**
     * @brief connectToSqlite 连接到sqlite本地数据库
     * @param path 数据库文件路径
     * @return 成功返回true
     */
    bool connectToSqlite(const QString& path);

    /**
     * @brief executeSql 执行sql语句
     * @param strSql sql语句
     * @return 成功返回true
     */
    bool executeSql(const QString& strSql);

    /**
     * @brief executeSqlWithResult
     * @param strSql sql语句
     * @param result 返回结果
     * @return 成功返回true
     */
    bool executeSqlWithResult(const QString& strSql, QVariant& result);

    /**
     * @brief readRecord 获取数据库数据
     * @param table 表名
     * @param fields 查询字段表达式
     * @param filter 筛选条件
     * @param records 查询结果
     * @return 成功返回true
     */
    bool readRecords(const QString&table, const QString& fields, const MSV& filter, VMSV&records);

    /**
     * @brief readRecords 运行sql获取数据库数据
     *  用于那些有特殊条件无法用第一个方法生成sql语句的情况
     * @param strSql sql语句
     * @param records 查询结果
     * @return 成功返回true
     */
    bool readRecords(const QString&strSql, VMSV& records);

    /**
     * @brief deleteRecord 删除表中数据
     * @param table 表名
     * @param filter 筛选条件
     * @return 成功返回true
     */
    bool deleteRecord(const QString& table, const MSV& filter);

    /**
     * @brief updateRecord 更新表中数据
     * @param table 表名
     * @param filter 筛选条件
     * @param data 修改的字段和值
     * @return 成功返回true
     */
    bool updateRecord(const QString& table, const MSV& filter, MSV& data);

    /**
     * @brief insertRecord 插入一条数据
     * @param table 表名
     * @param record 表数据
     * @return 成功返回true
     */
    bool insertRecord(const QString& table, const MSV& record);

    /**
     * @brief getLastError 获取上次访问数据库错误消息
     * @return 错误消息
     */
    QString getLastError();

private:

    /**
     * @brief getCondition 组装where子句
     * @param filter 筛选条件
     * @return 返回组装结果
     */
    QString getCondition(const MSV& filter);

    /**
     * @brief getVariantString 获取未知类型的变量为字符串
     *  如果是字符串则返回用单引号包裹的字符串，数字和函数名，直接转成字符串
     * @param var 输入变量
     * @return 返回字符串
     */
    QString getVariantString(const QVariant& var);

private:
    QSqlDatabase m_db;      // 数据库连接对象
    QString m_lastError;    // 上次访问数据库时的错误信息
    QString m_msDsn;        // access连接字段
};

#endif // DATABASEOPERATE_H
